package com.gcsoftware.gateway.filters.http.handler;

import com.gcsoftware.gateway.filters.http.response.RspValidations;
import com.gcsoftware.gateway.utils.regrex.RegexUtils;
import io.netty.handler.codec.http.*;
import org.apache.commons.lang3.StringUtils;
import org.littleshoot.proxy.HttpFiltersAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gcsoftware.gateway.filters.http.requst.ReqContentPull;
import com.gcsoftware.gateway.filters.http.response.RespContentRewrite;
import com.gcsoftware.gateway.utils.regrex.rexConst;

import io.netty.channel.ChannelHandlerContext;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by yinpeng on 18/1/23.
 */
public class gwMainHandlerFilter extends HttpFiltersAdapter
{
    private static final Logger log = LoggerFactory.getLogger(gwMainHandlerFilter.class);

    private volatile String remoteURL;
    private volatile boolean resetUri;
    private volatile Map<String, Object> argsMap;
    private volatile String sourceIp;

    public gwMainHandlerFilter(HttpRequest originalRequest, ChannelHandlerContext ctx, String RemoteAddr, boolean redirect)
    {
        super(originalRequest,ctx);
        resetUri = redirect;
        remoteURL = RemoteAddr;
        sourceIp = ((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();

    }

    public gwMainHandlerFilter(HttpRequest originalRequest, String RemoteAddr)
    {

       super(originalRequest);
       remoteURL = RemoteAddr;
    }


    public HttpRequest getOriginalRequest()
    {
        return originalRequest;
    }

    @Override
    public HttpResponse clientToProxyRequest(HttpObject httpObject)
    {
        return null;
    }

    @Override
    public HttpResponse proxyToServerRequest(HttpObject httpObject)
    {
        super.clientToProxyRequest(httpObject);
        if ("DsSolution".equals(HttpHeaders.getHeader((HttpMessage) httpObject, "RequestFrm"))) {
            log.debug("Request From DsSolution.The interfaces of webservice test connects.");
            this.resetUri = true;
        }
        if(resetUri)
        {
            if (httpObject instanceof HttpRequest) {
                HttpRequest httpRequest = (HttpRequest) httpObject;
                if (rexConst.REQUEST_TARGET_ORIGIN_FORM_PREFIX.matcher(httpRequest.getUri())
                        .lookingAt())
                {
                    String uriRemote = "http://" + remoteURL + httpRequest.getUri();
                    httpRequest.setUri(uriRemote);
                }
            }
        }
        if (httpObject instanceof FullHttpRequest)
        {

            FullHttpRequest fhReq = (FullHttpRequest) httpObject;
            ReqContentPull reqContentPull = new ReqContentPull();
            try {
                argsMap = reqContentPull.getReqRole(fhReq, new HashMap<String, Object>());
                if (null != argsMap) {
                    argsMap.put("sourceIp", sourceIp);
                    String remoteIp = null;
                    if (StringUtils.isNotBlank((String) argsMap.get("endPoint"))) {
                        remoteIp = RegexUtils.getSubUtilSimple((String) argsMap.get("endPoint"), "//(.*)?:");
                    } else {
                        remoteIp = RegexUtils.getSubUtilSimple(remoteURL,"(?:https?://)?(.*)?:");
                    }
                    argsMap.put("destinationIp", remoteIp);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                return new RspValidations().httpRspValidations(argsMap);
            }
        }
        return null;
    }

    @Override
    public HttpObject serverToProxyResponse(HttpObject httpObject)
    {
        super.serverToProxyResponse(httpObject);

        if (httpObject instanceof FullHttpResponse)
        {
            RespContentRewrite rewrite = new RespContentRewrite(argsMap);
            FullHttpResponse fhResp = rewrite.getContentAsString(originalRequest, (FullHttpResponse) httpObject);

            if (null != fhResp)
            {
                //log.debug("========MatchRequest:{}",argName);
                return fhResp;
            }
            else
            {
                log.warn("Can't rewrite the content as request {}", originalRequest);
                return httpObject;
            }
        }
        else
        {
            return httpObject;
        }

    }

    @Override
    public HttpObject proxyToClientResponse(HttpObject httpObject)
    {
        super.proxyToClientResponse(httpObject);
        return httpObject;
    }

}
